package br.com.vendaext.gerencial.apresentacao;

import java.util.Collection;

import javax.faces.component.UIComponent;
import javax.faces.event.ActionEvent;
import javax.inject.Named;

import org.hibernate.Criteria;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.primefaces.component.menuitem.MenuItem;
import org.primefaces.component.submenu.Submenu;
import org.primefaces.model.DefaultMenuModel;
import org.primefaces.model.MenuModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import br.com.vendaext.gerencial.entidades.Modulo;
import br.com.vendaext.gerencial.integracao.ModuloDAO;
import br.com.vendaext.gerencial.util.ELutil;
import br.com.vendaext.gerencial.util.WebUtil;

@Named
@Component
@Scope("session")
public class MenuHome {

	private MenuModel menuModel;
	String urlSelecionado;

	@Autowired
	ModuloDAO dao;

	public Collection<Modulo> carregarModulos() {
		return dao.getModulosPerfil(WebUtil.getUsuarioLogado().getPerfil());
	}

	
	/**
	 * Este método é utilizado para construir a árvore de menu de maneira recursiva.
	 * @param modulo
	 * @return
	 */
	private UIComponent constroiMenu(Modulo modulo, Collection<Modulo> modulosPerfil){
		
			if (modulo.getPai() == null && !dao.temFilhos(modulo)) {
				MenuItem itemMenu = new MenuItem();
				itemMenu.setValue(modulo.getNome());
				itemMenu.getAttributes().put("pagina", modulo.getUrl());
				itemMenu.getAttributes().put("bean", modulo.getBean());
				itemMenu.addActionListener(ELutil.createMethodActionListener("#{menuHome.changePageAction}", Void.TYPE,
						new Class[] { ActionEvent.class }));
				itemMenu.setUpdate("conteudo");
				return itemMenu;
				
			} else if (dao.temFilhos(modulo)){
				Submenu subMenu = new Submenu();
				subMenu.setLabel(modulo.getNome());
				
				for (Modulo filho : dao.getFilhos(modulo)) {
					if(modulosPerfil.contains(filho))
					subMenu.getChildren().add(constroiMenu(filho,modulosPerfil));
				}
				return subMenu;
			} else {
				MenuItem itemMenu = new MenuItem();
				itemMenu.setValue(modulo.getNome());
				itemMenu.getAttributes().put("pagina", modulo.getUrl());
				itemMenu.getAttributes().put("bean", modulo.getBean());
				itemMenu.addActionListener(ELutil.createMethodActionListener("#{menuHome.changePageAction}", Void.TYPE,
						new Class[] { ActionEvent.class }));
				itemMenu.setUpdate("conteudo");
				return itemMenu;
			}
			
	}

	@Transactional(readOnly=true)
	public void carregarMenu() {
		if (menuModel == null) {
			menuModel = new DefaultMenuModel();
			Collection<Modulo> mods = carregarModulos();
			
			for (Modulo modulo : mods) {
				//Apenas inclui os Componentes raiz, os sub-menus são incluídos de maneira recursiva.
				if(constroiMenu(modulo, mods) instanceof MenuItem && modulo.getPai()==null)
					menuModel.addMenuItem((MenuItem)constroiMenu(modulo,mods));
				else if(constroiMenu(modulo,mods) instanceof Submenu && modulo.getPai()==null)
					menuModel.addSubmenu((Submenu)constroiMenu(modulo,mods));
			}
			
			MenuItem menuSair = new MenuItem();
			menuSair.setValue("Sair");
			menuSair.setActionExpression(ELutil.createMethodExpression("#{loginHome.logout}", String.class, new Class[0]));
			menuModel.addMenuItem(menuSair);
		}
	}

	public MenuModel getMenuModel() {
		return menuModel;
	}

	public void setMenuModel(MenuModel menuModel) {
		this.menuModel = menuModel;
	}

	public void changePageAction(ActionEvent event) {
		try {

			MenuItem selectedMenuItem = (MenuItem) event.getComponent();
			ELutil.killSessionBean(selectedMenuItem.getAttributes().get("bean").toString());
			String pagina = selectedMenuItem.getAttributes().get("pagina").toString();
			setUrlSelecionado(pagina);

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public String getUrlSelecionado() {
		return urlSelecionado;
	}

	public void setUrlSelecionado(String urlSelecionado) {
		this.urlSelecionado = urlSelecionado;
	}
}
